/**
 * 分页列表 Composition Hook
 *
 * @example
 * ```typescript
 * import usePage from '@/hooks/page'
 *
 * const {
 *   dataList,
 *   loading,
 *   status,
 *   initData,
 *   loadMore,
 *   refreshData
 * } = usePage({
 *   url: ['shop', 'getList'], // 使用数组形式
 *   subForm: { category: 'electronics' },
 *   pageParamName: { page: 'pageNo', limit: 'pageSize' },
 *   onSuccess: (data) => console.log('数据加载成功', data),
 *   onError: (error) => console.error('加载失败', error)
 * })
 *
 * // 初始化数据
 * onMounted(() => {
 *   initData()
 * })
 * ```
 */

import { ref, computed, reactive, toRefs } from "vue";
import _api from "@/api";

// 类型定义
interface PageOptions {
    /** API 路径配置,使用数组形式: ['shop', 'getList'] */
    url: string[];
    /** 额外的查询参数 */
    subForm?: Record<string, any>;
    /** 分页参数名配置 */
    pageParamName?: {
        page?: string;
        limit?: string;
    };
    /** 每页数量,默认 10 */
    pageSize?: number;
    /** 数据成功回调 */
    onSuccess?: (data: any) => void;
    /** 数据错误回调 */
    onError?: (error: any) => void;
    /** 数据转换函数 */
    transform?: (response: any) => { items: any[]; total?: number };
}

interface ApiResponse {
    code: number;
    result?: {
        items: any[];
        total?: number;
        [key: string]: any;
    };
    data?: {
        list: any[];
        total?: number;
        [key: string]: any;
    };
    msg?: string;
}

type LoadStatus = "down" | "loading" | "nomore";

export default function usePage(options: PageOptions) {
    // 参数验证
    if (!options?.url || !Array.isArray(options.url) || options.url.length === 0) {
        console.error('[usePage] url 配置必须是非空数组，如: ["shop", "getList"]');
        throw new Error("url 配置必须是非空数组");
    }

    // 分页参数名配置
    const pageParamName = {
        page: options.pageParamName?.page || "page",
        limit: options.pageParamName?.limit || "pageSize"
    };

    // 查询参数
    const subForm = reactive({
        [pageParamName.page]: 1,
        [pageParamName.limit]: options.pageSize || 10,
        ...options.subForm
    });

    // 响应式数据
    const dataList = ref<any[]>([]);
    const loading = ref(false);
    const status = ref<LoadStatus>("down");
    const dataTotal = ref<number>(0);
    const error = ref<Error | null>(null);

    // 计算属性
    const dataLength = computed(() => dataList.value?.length || 0);
    const hasData = computed(() => dataLength.value > 0);
    const isLoading = computed(() => status.value === "loading");
    const isNoMore = computed(() => status.value === "nomore");
    const hasMore = computed(() => status.value === "down");
    const currentPage = computed(() => subForm[pageParamName.page]);

    /**
     * 构建 API 请求函数
     */
    const buildApi = (): Function => {
        try {
            let api: any = _api;

            // 遍历 url 数组，逐层访问 API 对象
            for (const key of options.url) {
                if (!api[key]) {
                    throw new Error(`API 路径不存在: ${key}，完整路径: ${options.url.join(".")}`);
                }
                api = api[key];
            }

            // 确保最终返回的是一个函数
            if (typeof api !== "function") {
                throw new Error(`API 路径 ${options.url.join(".")} 不是一个函数`);
            }

            return api;
        } catch (err: any) {
            console.error("[usePage] 构建 API 失败:", err);
            throw err;
        }
    };

    /**
     * 数据转换函数
     */
    const transformResponse = (response: ApiResponse) => {
        // 如果用户提供了自定义转换函数
        if (options.transform) {
            return options.transform(response);
        }

        // 默认转换逻辑
        let items: any[] = [];
        let total: number | undefined;

        if (response.result) {
            items = response.result.items || [];
            total = response.result.total;
        } else if (response.data) {
            items = response.data.list || [];
            total = response.data.total;
        }

        return { items, total };
    };

    /**
     * 获取列表数据
     */
    const getDataList = async (): Promise<{ length: number; data: any[] } | null> => {
        try {
            loading.value = true;
            error.value = null;

            // 构建 API 函数
            const apiFn = buildApi();

            // 如果是第一页,清空数据
            if (subForm[pageParamName.page] === 1) {
                dataList.value = [];
            }

            // 发起请求
            const response: ApiResponse = await apiFn(subForm);

            // 检查响应状态
            if (response.code !== 0 && response.code) {
                throw new Error(response.msg || "请求失败");
            }

            // 转换数据
            const { items, total } = transformResponse(response);

            // 更新数据
            if (subForm[pageParamName.page] === 1) {
                dataList.value = items || [];
                if (total !== undefined) {
                    dataTotal.value = total;
                }
            } else {
                dataList.value = [...dataList.value, ...(items || [])];
            }

            // 更新状态
            const itemsLength = items?.length || 0;
            status.value = itemsLength < subForm[pageParamName.limit] ? "nomore" : "down";

            // 成功回调
            options.onSuccess?.(items);

            console.log("[usePage] 数据加载成功:", {
                page: subForm[pageParamName.page],
                length: itemsLength,
                total: dataTotal.value,
                status: status.value
            });

            return {
                length: itemsLength,
                data: items || []
            };
        } catch (err: any) {
            console.error("[usePage] 数据加载失败:", err);
            error.value = err;
            status.value = "down";

            // 错误回调
            options.onError?.(err);

            // 显示错误提示
            uni.showToast({
                title: err.message || "加载失败",
                icon: "none",
                duration: 2000
            });

            return null;
        } finally {
            loading.value = false;
        }
    };

    /**
     * 初始化数据(重置到第一页)
     */
    const initData = async () => {
        console.log("[usePage] 初始化数据");
        subForm[pageParamName.page] = 1;
        status.value = "down";
        dataList.value = [];
        await getDataList();
    };

    /**
     * 刷新当前页数据
     */
    const refreshData = async () => {
        console.log("[usePage] 刷新数据");
        await getDataList();
    };

    /**
     * 加载更多数据
     */
    const loadMore = async () => {
        // 防止重复加载
        if (status.value === "nomore" || status.value === "loading") {
            console.log("[usePage] 无法加载更多:", status.value);
            return;
        }

        console.log("[usePage] 加载更多:", {
            currentPage: subForm[pageParamName.page],
            status: status.value
        });

        // 页码+1
        subForm[pageParamName.page]++;
        status.value = "loading";

        try {
            const result = await getDataList();

            if (!result) {
                // 加载失败,回退页码
                subForm[pageParamName.page]--;
                status.value = "down";
            }
        } catch (err) {
            // 加载失败,回退页码
            subForm[pageParamName.page]--;
            status.value = "down";
        }
    };

    /**
     * 页面触底事件(uni-app)
     */
    const onReachBottom = async () => {
        await loadMore();
    };

    /**
     * scroll-view 触底事件
     */
    const scrolltolower = async () => {
        await loadMore();
    };

    /**
     * 重置分页数据
     */
    const resetPageData = () => {
        console.log("[usePage] 重置数据");
        subForm[pageParamName.page] = 1;
        dataList.value = [];
        dataTotal.value = 0;
        status.value = "down";
        loading.value = false;
        error.value = null;
    };

    /**
     * 更新查询参数并重新加载第一页
     */
    const updateSubForm = async (newParams: Record<string, any>, reload = true) => {
        Object.assign(subForm, newParams);
        if (reload) {
            await initData();
        }
    };

    /**
     * 删除列表项
     */
    const removeItem = (index: number) => {
        if (index >= 0 && index < dataList.value.length) {
            dataList.value.splice(index, 1);
            dataTotal.value = Math.max(0, dataTotal.value - 1);
        }
    };

    /**
     * 根据条件删除列表项
     */
    const removeItemBy = (predicate: (item: any, index: number) => boolean) => {
        const index = dataList.value.findIndex(predicate);
        if (index !== -1) {
            removeItem(index);
        }
    };

    /**
     * 更新列表项
     */
    const updateItem = (index: number, newData: any) => {
        if (index >= 0 && index < dataList.value.length) {
            dataList.value[index] = { ...dataList.value[index], ...newData };
        }
    };

    /**
     * 根据条件更新列表项
     */
    const updateItemBy = (predicate: (item: any, index: number) => boolean, newData: any) => {
        const index = dataList.value.findIndex(predicate);
        if (index !== -1) {
            updateItem(index, newData);
        }
    };

    return {
        // 响应式数据
        dataList,
        loading,
        status,
        dataTotal,
        error,
        subForm: toRefs(subForm),

        // 计算属性
        dataLength,
        hasData,
        isLoading,
        isNoMore,
        hasMore,
        currentPage,

        // 方法
        getDataList,
        initData,
        refreshData,
        loadMore,
        onReachBottom,
        scrolltolower,
        resetPageData,
        updateSubForm,
        removeItem,
        removeItemBy,
        updateItem,
        updateItemBy
    };
}
